#pragma once

#include <string>
#include <map>
#include <list>

#include "../Object.h"
#include "../SQLDbTypedObject.h"
#include "../SQLObjectImpl.h"
#include "../SQLHint.h"
#include "../SQLLimit.h"
#include "../SQLOrderBy.h"

#include "SQLSelectQuery.h"

class SQLSelectQueryBlock;
class SQLWithSubqueryClause;
class SQLASTVisitor;

class SQLSelect : virtual public SQLObjectImpl, virtual public SQLDbTypedObject
{
public:
  SQLWithSubqueryClause_ptr withSubQuery;
  SQLSelectQuery_ptr query;
  SQLOrderBy_ptr orderBy;
  SQLLimit_ptr limit;

  SQLHint_list_ptr hints;

  SQLObject_ptr restriction;

  BOOL_ptr forBrowse;
  string_list_ptr forXmlOptions;
  SQLExpr_ptr xmlPath;

  SQLExpr_ptr rowCount;
  SQLExpr_ptr offset;

  SQLHint_ptr headHint;

  SQLSelect();
  SHAREDOBJECT(SQLSelect);

  SQLHint_list_ptr getHints();

  int getHintsSize();

  SQLSelect(SQLSelectQuery_ptr query);

  SQLWithSubqueryClause_ptr getWithSubQuery();

  void setWithSubQuery(SQLWithSubqueryClause_ptr x);

  SQLSelectQuery_ptr getQuery();

  void setQuery(SQLSelectQuery_ptr query);

  SQLSelectQueryBlock_ptr getQueryBlock();

  SQLOrderBy_ptr getOrderBy();

  void setOrderBy(SQLOrderBy_ptr orderBy);

  void accept0(SQLASTVisitor_ptr v);

  // DbType getDbType();

  // SQLSelect_ptr clone();
  virtual SQLObject_ptr clone();

  // BOOL_ptr isSimple() ;

  SQLObject_ptr getRestriction() ;

  void setRestriction(SQLObject_ptr restriction);

  BOOL_ptr isForBrowse();

  void setForBrowse(BOOL_ptr forBrowse);

  string_list_ptr getForXmlOptions();

  int getForXmlOptionsSize();

  SQLExpr_ptr getRowCount();

  void setRowCount(SQLExpr_ptr rowCount);

  SQLHint_ptr getHeadHint() ;

  void setHeadHint(SQLHint_ptr headHint);

  SQLExpr_ptr getOffset();

  void setOffset(SQLExpr_ptr offset);

  SQLExpr_ptr getXmlPath();

  void setXmlPath(SQLExpr_ptr xmlPath);

  string_list_ptr computeSelecteListAlias();

  SQLSelectQueryBlock_ptr getFirstQueryBlock();

  bool equals(Object_ptr o) override;
  // bool equals(Object *o) override;

  int hashCode() override;

  BOOL_ptr addWhere(SQLExpr_ptr where);

  BOOL_ptr replace(SQLSelectQuery_ptr cmp, SQLSelectQuery_ptr target);

  SQLLimit_ptr getLimit() ;

  void setLimit(SQLLimit_ptr x) ;

  bool containsAttribute(string_ptr name){};
  void addBeforeComment(string_list_ptr comments){};
  string_list_ptr getAfterCommentsDirect(){};
  string_list_ptr getBeforeCommentsDirect(){};
  void addAfterComment(string_ptr comment){};
  void addAfterComment(string_list_ptr comments){};
  bool hasBeforeComment(){};
  bool hasAfterComment(){};
};

// typedef boost::shared_ptr<SQLSelect> SQLSelect_ptr;